{% extends "base_config.html" %}
{% block content %}
<div class="page">
    <div class="section">
        <div id="overlay" style="display: none;"></div>
        <h2 class="section-title">
            <img class="card-icon" src="/static/assets/icons/automation.svg?v={{ khoj_version }}" alt="Automate">
            <span class="card-title-text">Automate (Preview)</span>
            <div class="instructions">
                Automations allow you to schedule smart reminders using Khoj. This is an experimental feature, so your results may vary! Send any feedback to <a class="inline-link-light" href="mailto:team@khoj.dev">team@khoj.dev</a>.
            </div>
            <div class="instructions notice">
                Sending automation results to <a class="inline-link-light" href="mailto:{{ username}}">{{ username }}</a>.
            </div>
        </h2>
        <div class="section-body">
            <button id="create-automation-button" type="button" class="positive-button">
               <img class="automation-action-icon" src="/static/assets/icons/new.svg" alt="Automations">
               <span id="create-automation-button-text">Build Your Own</span>
            </button>
            <div id="automations" class="section-cards"></div>
            <div id="suggested-automations">
                <h2 class="section-title">
                    <span class="card-title-text">Suggested Automations</span>
                </h2>
                <div id="suggested-automations-list" class="section-cards"></div>
            </div>
        </div>
    </div>
    <div id="footer">
        <a href="/">Back to Chat</a>
    </div>
</div>
<script>
    document.getElementById("automations-nav").classList.add("khoj-nav-selected");
</script>

<script src="/static/assets/natural-cron.min.js"></script>
<style>
    td {
        padding: 10px 0;
    }
    #overlay {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: black;
        opacity: 0.5;
        z-index: 1;
    }
    div.automation {
        width: 100%;
        height: 100%;
        grid-template-rows: none;
        background-color: white;
        border-radius: 20px;
        padding: 20px;
        box-shadow: rgba(3, 3, 3, 0.08) 0px 1px 12px;
        transition: box-shadow 0.3s ease, transform 0.3s ease;
    }

    div#footer {
        width: auto;
        padding: 10px;
        background-color: var(--background-color);
        border-top: 1px solid var(--main-text-color);
        text-align: left;
        margin-top: 12px;
        margin-bottom: 12px;
    }

    div#footer a {
        font-size: 18px;
        font-weight: bold;
        color: var(--primary-color);
    }

    img.automation-share-icon,
    img.automation-edit-cancel-icon,
    img.automation-edit-icon {
        width: 24px;
        height: 24px;
        object-fit: cover;
        cursor: pointer;
        margin: auto;
    }

    textarea.fake-input,
    input.fake-input {
        height: auto;
        padding-top: 0px;
        padding-bottom: 0px;
        padding-left: 0px;
        padding-right: 0px;
        border: none;
    }

    #create-automation-button {
        width: auto;
    }

    div.notice {
        border-top: 1px solid black;
        padding-top: 8px;
    }

    div#suggested-automations-list,
    div#automations {
        margin-bottom: 12px;
        grid-template-columns: 1fr 1fr;
    }

    button.negative-button {
        background-color: gainsboro;
    }
    .positive-button {
        background-color: var(--primary-hover)
    }
    .positive-button:hover {
        background-color: var(--summer-sun);
    }

    div.automation-buttons {
        display: grid;
        grid-gap: 8px;
        grid-template-columns: 1fr 1fr 1fr;
    }

    button.save-automation-button {
        background-color: var(--summer-sun);
    }

    button.save-automation-button,
    button.cancel-edit-automation-button,
    button.send-preview-automation-button,
    button.delete-automation-button {
        padding: 8px;
        margin-bottom: 0;
    }

    button.send-preview-automation-button {
        border-color: var(--summer-sun);
    }

    button.save-automation-button:hover {
        background-color: var(--primary-hover);
    }

    div.new-automation {
        border-radius: 20px;
        box-shadow: 0 4px 6px 0 hsla(0, 0%, 0%, 0.2);
        margin-bottom: 20px;
        transition: box-shadow 0.3s ease, transform 0.3s ease;
        position: absolute;
        top: 50%;
        left: 50%;
        width: auto;
        transform: translate(-50%, -50%);
        z-index: 2;
        height: auto;
    }

    div.automation:not(.new-automation):hover {
        box-shadow: 0 10px 15px 0 hsla(0, 0%, 0%, 0.1);
        transform: translateY(-5px);
    }

    .hide-details {
        display: none !important;
    }

    div.card-header {
        display: grid;
        grid-template-rows: auto 1fr;
        grid-gap: 8px;
        align-items: baseline;
    }
    input.schedule {
        font-size: medium;
        height: auto;
        font-weight: lighter !important;
    }

    h2.section-title {
        font-size: larger;
    }

    div.card-header input {
        font-weight: bold;
        margin-bottom: 0 !important;
    }

    div.automation textarea {
        width: 100%;
        box-sizing: border-box;
        border-radius: 4px;
        resize: none;
    }

    img.promo-image {
        width: 100%;
        height: 100px;
        object-fit: cover;
        border-radius: 4px;
    }


    div.card-header textarea,
    div.card-header input,
    div.card-header:hover {
        cursor: pointer;
    }

    div.toggle-icon {
        width: 24px;
        height: 24px;
    }

    div.subject-wrapper {
        display: grid;
        grid-template-columns: 1fr auto auto;
        grid-gap: 8px;
    }

    div.subject-wrapper p {
        margin: 0;
    }

    @keyframes confirmation {
        0% { background-color: normal; transform: scale(1); }
        50% { background-color: var(--primary); transform: scale(1.1); }
        100% { background-color: normal; transform: scale(1); }
    }

    .confirmation {
        animation: confirmation 1s;
    }

    @media screen and (max-width: 600px) {
        div#automations,
        div#suggested-automations-list {
            grid-template-columns: 1fr;
        }
        div.automation-buttons {
            grid-template-columns: 1fr;
        }
        div.new-automation {
            width: 100%;
            height: auto;
        }
    }

</style>
<script>
    function deleteAutomation(automationId) {
        const AutomationList = document.getElementById("automations");
        if ("{{ username }}" === "None") {
            const AutomationItem = document.getElementById(`automation-card-${automationId}`);
            AutomationList.removeChild(AutomationItem);
            // Remove the Automation from the DOM and return
            AutomationItem.remove();
            document.getElementById('overlay').style.display = 'none';
            return;
        }
        fetch(`/api/automation?automation_id=${automationId}`, {
            method: 'DELETE',
        })
        .then(response => {
            if (response.status == 200 || response.status == 204) {
                const AutomationItem = document.getElementById(`automation-card-${automationId}`);
                AutomationList.removeChild(AutomationItem);
                document.getElementById('overlay').style.display = 'none';
            }
        });
    }

    function updateAutomationRow(automation) {
        let automationId = automation.id;
        let automationNextRun = `Next run at ${automation.next}\nCron: ${automation.crontime}`;

        let scheduleEl = document.getElementById(`automation-schedule-${automationId}`);
        scheduleEl.setAttribute('data-original', automation.schedule);
        scheduleEl.setAttribute('data-cron', automation.crontime);
        scheduleEl.setAttribute('title', automationNextRun);
        scheduleEl.value = automation.schedule;

        let subjectEl = document.getElementById(`automation-subject-${automationId}`);
        subjectEl.setAttribute('data-original', automation.subject);
        subjectEl.value = automation.subject;

        let queryEl = document.getElementById(`automation-queryToRun-${automationId}`);
        queryEl.setAttribute('data-original', automation.query_to_run);
        queryEl.value = automation.query_to_run;
    }

    function onClickEditAutomationCard(automationId) {
        const automationIDElements = document.querySelectorAll(`.${automationId}`);
        automationIDElements.forEach(el => {
            if (el.classList.contains("automation-edit-icon")) {
                el.classList.remove("automation-edit-icon");
                el.classList.add("automation-edit-cancel-icon");
                el.src = "/static/assets/icons/cancel.svg";
                el.onclick = function(event) { clickCancelEdit(event, automationId); };
            }

            if (el.classList.contains("hide-details")) {
                el.classList.add("hide-details-placeholder");
                el.classList.remove("hide-details");
            }
            if (el.classList.contains("fake-input")) {
                el.classList.add("fake-input-placeholder");
                el.classList.remove("fake-input");
            }
        });
    }

    function sendAPreviewAutomation(automationId) {
        const notificationEl = document.getElementById(`automation-success-${automationId}`);

        fetch(`/api/trigger/automation?automation_id=${automationId}`, { method: 'POST' })
            .then(response =>
                {
                    if (!response.ok) {
                        throw new Error('Network response was not ok');
                    }
                    return response;
                })
            .then(automations => {
                notificationEl.style.display = 'block';
                notificationEl.textContent = "Automation triggered. Check your inbox in a few minutes!";
            })
            .catch(error => {
                notificationEl.style.display = 'block';
                notificationEl.textContent = "Sorry, something went wrong. Try again later."
            })

    }

    function clickCancelEdit(event, automationId) {
        event.preventDefault();
        event.stopPropagation();
        const automationIDElements = document.querySelectorAll(`.${automationId}`);
        automationIDElements.forEach(el => {
            if (el.classList.contains("automation-edit-cancel-icon")) {
                el.classList.remove("automation-edit-cancel-icon");
                el.classList.add("automation-edit-icon");
                el.src = "/static/assets/icons/pencil-edit.svg";
                el.onclick = function() { onClickEditAutomationCard(automationId); };
            }

            if (el.classList.contains("hide-details-placeholder")) {
                el.classList.remove("hide-details-placeholder");
                el.classList.add("hide-details");
            }
            if (el.classList.contains("fake-input-placeholder")) {
                el.classList.remove("fake-input-placeholder");
                el.classList.add("fake-input");
            }
        })
    }

    function copyShareLink(event, automationId, subject, crontime, queryToRun) {
        event.preventDefault();
        event.stopPropagation();

        const encodedSubject = encodeURIComponent(subject);
        const encodedCrontime = encodeURIComponent(crontime);
        const encodedQueryToRun = encodeURIComponent(queryToRun);

        const shareLink = `${window.location.origin}/automations?subject=${encodedSubject}&crontime=${encodedCrontime}&queryToRun=${encodedQueryToRun}`;
        const button = document.getElementById(`share-link-${automationId}`);

        navigator.clipboard.writeText(shareLink).then(() => {
                button.src = "/static/assets/icons/copy-button-success.svg";
                setTimeout(() => {
                    button.src = "/static/assets/icons/share.svg";
                }, 1000);
            }).catch((error) => {
                console.error("Error copying share link output to clipboard:", error);
                setTimeout(() => {
                    button.src = "/static/assets/icons/share.svg";
                }, 1000);
            });
    }

    function generateAutomationRow(automation, isSuggested=false) {
        let automationId = automation.id;
        let automationNextRun = `Next run at ${automation.next}\nCron: ${automation.crontime}`;
        let automationEl = document.createElement("div");
        automationEl.innerHTML = `
            <div class="card automation" id="automation-card-${automationId}">
                <div class="card-header" onclick="onClickEditAutomationCard('${automationId}')">
                    <div class="subject-wrapper">
                        <input type="text"
                            id="automation-subject-${automationId}"
                            class="${automationId} fake-input"
                            name="subject"
                            data-original="${automation.subject}"
                            value="${automation.subject}">
                        <img class=automation-share-icon id="share-link-${automationId}" src="/static/assets/icons/share.svg" alt="Share" onclick="copyShareLink(event, '${automationId}', '${automation.subject}', '${automation.crontime}', '${automation.query_to_run}')">
                        <img class="automation-edit-icon ${automationId}" src="/static/assets/icons/pencil-edit.svg" onclick="onClickEditAutomationCard('${automationId}')" alt="Automations">
                    </div>
                    <input type="text"
                       id="automation-schedule-${automationId}"
                       name="schedule"
                       class="schedule ${automationId} fake-input"
                       data-cron="${automation.crontime}"
                       data-original="${automation.schedule}"
                       title="${automationNextRun}"
                       value="${automation.schedule}">
                    <textarea id="automation-queryToRun-${automationId}"
                        class="automation-instructions ${automationId} fake-input"
                        data-original="${automation.query_to_run}"
                        name="query-to-run">${automation.query_to_run}</textarea>
                    ${isSuggested ?
                        `<img class=promo-image src="${automation.promoImage}" alt="Promo Image">`:
                        ""
                    }
                </div>
                <div id="automation-buttons-wrapper">
                    <div class="automation-buttons">
                        ${isSuggested ?
                            `<div id="empty-div"></div>
                            <div id="empty-div"></div>`:
                            `
                            <button type="button"
                                    class="delete-automation-button negative-button"
                                    id="delete-automation-button-${automationId}">Delete</button>
                            <button type="button"
                                    class="send-preview-automation-button positive-button"
                                    title="Immediately get a preview of this automation"
                                    onclick="sendAPreviewAutomation('${automationId}')">Preview</button>
                            `
                        }
                        <button type="button"
                                class="save-automation-button positive-button"
                                id="save-automation-button-${automationId}">
                                    ${isSuggested ? "Add" : "Save"}
                                </button>
                    </div>
                </div>
                <div id="automation-success-${automationId}" style="display: none;"></div>
            </div>
        `;

        let automationButtonsSection = automationEl.querySelector(".automation-buttons");
        if (!isSuggested) {
            automationButtonsSection.classList.add("hide-details");
            automationButtonsSection.classList.add(automationId);
        }

        let saveAutomationButtonEl = automationEl.querySelector(`#save-automation-button-${automation.id}`);
        saveAutomationButtonEl.addEventListener("click", async () => { await saveAutomation(automation.id, isSuggested); });
        let deleteAutomationButtonEl = automationEl.querySelector(`#delete-automation-button-${automation.id}`);
        if (deleteAutomationButtonEl) {
            deleteAutomationButtonEl.addEventListener("click", () => {
                deleteAutomation(automation.id);
                document.getElementById('overlay').style.display = 'none';
            });
        }
        let cancelEditAutomationButtonEl = automationEl.querySelector(`#cancel-edit-automation-button-${automation.id}`);
        if (cancelEditAutomationButtonEl) {
            cancelEditAutomationButtonEl.addEventListener("click", (event) => {
                clickCancelEdit(event, automation.id);
                document.getElementById('overlay').style.display = 'none';
            });
        }

        return automationEl.firstElementChild;
    }

    let timestamp = Math.floor(Date.now() / 1000);

    let suggestedAutomationsMetadata = [
        {
            "subject": "Weekly Newsletter",
            "query_to_run": "Compile a message including: 1. A recap of news from last week 2. A reminder to work out and stay hydrated 3. A quote to inspire me for the week ahead",
            "schedule": "9AM every Monday",
            "next": "Next run at 9AM on Monday",
            "crontime": "0 9 * * 1",
            "id": "suggested-automation" + timestamp,
            "promoImage": "https://assets.khoj.dev/abstract_rectangles.webp",
        },
        {
            "subject": "Daily Weather Update",
            "query_to_run": "Get the weather forecast for today",
            "schedule": "9AM every morning",
            "next": "Next run at 9AM today",
            "crontime": "0 9 * * *",
            "id": "suggested-automation" + (timestamp + 1),
            "promoImage": "https://assets.khoj.dev/blue_waves.webp",
        },
        {
            "subject": "Front Page of Hacker News",
            "query_to_run": "Summarize the top 5 posts from https://news.ycombinator.com/best and share them with me, including links",
            "schedule": "9PM on every Wednesday",
            "next": "Next run at 9PM on Wednesday",
            "crontime": "0 21 * * 3",
            "id": "suggested-automation" + (timestamp + 2),
            "promoImage": "https://assets.khoj.dev/purple_triangles.webp",
        },
        {
            "subject": "Market Summary",
            "query_to_run": "Get the market summary for today and share it with me. Focus on tech stocks and the S&P 500.",
            "schedule": "9AM on every weekday",
            "next": "Next run at 9AM on Monday",
            "crontime": "0 9 * * 1-5",
            "id": "suggested-automation" + (timestamp + 3),
            "promoImage": "https://assets.khoj.dev/blue_gears.webp",
        }
    ];

    function listAutomations() {
        const AutomationsList = document.getElementById("automations");
        fetch('/api/automations')
            .then(response => response.json())
            .then(automations => {
                if (!automations?.length > 0) return;
                AutomationsList.innerHTML = ''; // Clear existing content
                AutomationsList.append(...automations.map(automation => generateAutomationRow(automation)));
                // Check if any of the automations 'query-to-run' fields match the suggested automations
                automations.forEach(automation => {
                    suggestedAutomationsMetadata.forEach(suggestedAutomation => {
                        if (automation.query_to_run === suggestedAutomation.query_to_run) {
                            let suggestedAutomationEl = document.getElementById(`automation-card-${suggestedAutomation.id}`);
                            suggestedAutomationEl.remove();
                        }
                    });
                });
                // Check if subject, crontime, query_to_run are all filled out. If so, show it as a populated suggested automation.
                const subject = "{{ subject }}";
                const crontime = "{{ crontime }}";
                const query = "{{ queryToRun }}";

                if (subject && crontime && query) {
                    const preFilledAutomation = createPreFilledAutomation(subject, crontime, query);
                }
            });
    }

    if ("{{ username }}" !== "None") {
        listAutomations();
    } else {
        // Check if subject, crontime, query_to_run are all filled out. If so, show it as a populated suggested automation.
        const subject = "{{ subject }}";
        const crontime = "{{ crontime }}";
        const query = "{{ queryToRun }}";

        if (subject && crontime && query) {
            const preFilledAutomation = createPreFilledAutomation(subject, crontime, query);
        }
    }

    if (suggestedAutomationsMetadata.length > 0) {
        suggestedAutomationsMetadata.forEach(automation => {
            automation.id = "suggested-automation" + timestamp;
            timestamp++;
        });
    }




    function listSuggestedAutomations() {
        const SuggestedAutomationsList = document.getElementById("suggested-automations-list");
        SuggestedAutomationsList.innerHTML = ''; // Clear existing content
        SuggestedAutomationsList.append(...suggestedAutomationsMetadata.map(automation => generateAutomationRow(automation, true)));
    }
    listSuggestedAutomations();

    function enableSaveOnlyWhenInputsChanged() {
        const inputs = document.querySelectorAll('input[name="schedule"], textarea[name="query-to-run"], input[name="subject"]');
        inputs.forEach(input => {
            input.addEventListener('change', function() {
                // Get automation id by splitting the id by "-" and taking all elements after the second one
                const automationId = this.id.split("-").slice(2).join("-");
                let anyChanged = false;
                let inputNameStubs = ["subject", "query-to-run", "schedule"]
                for (let stub of inputNameStubs) {
                    let el = document.getElementById(`automation-${stub}-${automationId}`);
                    let originalValue = el.getAttribute('data-original');
                    let currentValue = el.value;
                    if (originalValue !== currentValue) {
                        anyChanged = true;
                        break;
                    }
                }
                document.getElementById(`save-automation-button-${automationId}`).disabled = !anyChanged;
            });
        });
    }

    function createScheduleSelector(automationId) {
        var scheduleContainer = document.createElement('div');
        scheduleContainer.id = `schedule-container-${automationId}`;

        var frequencyLabel = document.createElement('label');
        frequencyLabel.for = `frequency-selector-${automationId}`;
        frequencyLabel.textContent = 'Every';
        var frequencySelector = document.createElement('select')
        frequencySelector.id = `frequency-selector-${automationId}`;
        var dayLabel = document.createElement('label');
        dayLabel.id = `day-selector-label-${automationId}`;
        dayLabel.for = `day-selector-${automationId}`;
        dayLabel.textContent = 'on';
        var daySelector = document.createElement('select');
        daySelector.id = `day-selector-${automationId}`;
        var dateLabel = document.createElement('label');
        dateLabel.id = `date-label-${automationId}`;
        dateLabel.for = `date-selector-${automationId}`;
        dateLabel.textContent = 'on the';
        var dateSelector = document.createElement('select');
        dateSelector.id = `date-selector-${automationId}`;
        var timeLabel = document.createElement('label');
        timeLabel.for = `time-selector-${automationId}`;
        timeLabel.textContent = 'at';
        var timeSelector = document.createElement('select');
        timeSelector.id = `time-selector-${automationId}`;


        // Populate frequency selector with options for day, week, and month
        var frequencies = ['day', 'week', 'month'];
        for (var i = 0; i < frequencies.length; i++) {
            var option = document.createElement('option');
            option.value = frequencies[i];
            option.text = frequencies[i];
            frequencySelector.appendChild(option);
        }

        // Event listener for frequency selector change
        frequencySelector.addEventListener('change', function() {
            switch (this.value) {
                case 'day':
                    daySelector.style.display = 'none';
                    dateSelector.style.display = 'none';
                    break;
                case 'week':
                    daySelector.style.display = 'block';
                    dateSelector.style.display = 'none';
                    break;
                case 'month':
                    daySelector.style.display = 'none';
                    dateSelector.style.display = 'block';
                    break;
            }
        });

        // Populate the date selector with options for each day of the month
        for (var i = 1; i <= 31; i++) {
            var option = document.createElement('option');
            option.value = i;
            option.text = i;
            dateSelector.appendChild(option);
        }

        // Populate the day selector with options for each day of the week
        var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        for (var i = 0; i < days.length; i++) {
            var option = document.createElement('option');
            option.value = i;
            option.text = days[i];
            daySelector.appendChild(option);
        }

        var timePeriods = ['AM', 'PM'];
        // Populate the time selector with options for each hour of the day
        for (var i = 0; i < timePeriods.length; i++) {
            for (var hour = 0; hour < 12; hour++) {
                for (var minute = 0; minute < 60; minute+=15) {
                    // Ensure all minutes are two digits
                    var paddedMinute = String(minute).padStart(2, '0');
                    var option = document.createElement('option');
                    var friendlyHour = hour === 0 ? 12 : hour;
                    option.value = `${friendlyHour}:${paddedMinute} ${timePeriods[i]}`;
                    option.text = `${friendlyHour}:${paddedMinute} ${timePeriods[i]}`;
                    timeSelector.appendChild(option);
                }
            }
        }

        // Populate date selector with options 1 through 31
        for (var i = 1; i <= 31; i++) {
            var option = document.createElement('option');
            option.value = i;
            option.text = i;
            dateSelector.appendChild(option);
        }

        var hoursMinutesSelectorContainer = document.createElement('div');
        hoursMinutesSelectorContainer.classList.add('hours-minutes-selector-container');
        hoursMinutesSelectorContainer.appendChild(timeLabel);
        hoursMinutesSelectorContainer.appendChild(timeSelector);

        scheduleContainer.appendChild(frequencyLabel);
        scheduleContainer.appendChild(frequencySelector);
        scheduleContainer.appendChild(dayLabel);
        scheduleContainer.appendChild(daySelector);
        scheduleContainer.appendChild(dateLabel);
        scheduleContainer.appendChild(dateSelector);
        scheduleContainer.appendChild(hoursMinutesSelectorContainer);

        return scheduleContainer;
    }

    function setupScheduleViewListener(cronString, automationId) {
        // Parse the cron string
        var cronParts = cronString.split(' ');
        var minutes = cronParts[0];
        var hours = cronParts[1];
        var dayOfMonth = cronParts[2];
        var month = cronParts[3];
        var dayOfWeek = cronParts[4];

        var timeSelector = document.getElementById(`time-selector-${automationId}`);

        // Set the initial value of the time selector based on the cron string. Convert 24-hour time to 12-hour time
        if (hours === '*' && minutes === '*') {
            var currentTime = new Date();
            hours = currentTime.getHours();
            minutes = currentTime.getMinutes();
        }
        var hours = parseInt(hours);
        var minutes = parseInt(minutes);
        var timePeriod = hours >= 12 ? 'PM' : 'AM';
        hours = hours % 12;
        hours = hours ? hours : 12; // 0 should be 12
        minutes = Math.round(minutes / 15) * 15;
        minutes = String(minutes).padStart(2, '0');
        // Resolve minutes to the nearest 15 minute interval

        timeSelector.value = `${hours}:${minutes} ${timePeriod}`;

        const frequencySelector = document.getElementById(`frequency-selector-${automationId}`);
        const daySelector = document.getElementById(`day-selector-${automationId}`);
        const daySelectorLabel = document.getElementById(`day-selector-label-${automationId}`);
        const dateSelector = document.getElementById(`date-selector-${automationId}`);
        const dateLabel = document.getElementById(`date-label-${automationId}`);

        // Event listener for frequency selector change
        frequencySelector.addEventListener('change', function() {
            processFrequencySelector(frequencySelector, daySelector, daySelectorLabel, dateSelector, dateLabel);
        });

        // Set the initial value based on the frequency selector value
        processFrequencySelector(frequencySelector, daySelector, daySelectorLabel, dateSelector, dateLabel);
    }

    function processFrequencySelector(frequencySelector, daySelector, daySelectorLabel, dateSelector, dateLabel) {
        switch (frequencySelector.value) {
            case 'day':
                daySelector.style.display = 'none';
                dateSelector.style.display = 'none';
                daySelectorLabel.style.display = 'none';
                dateLabel.style.display = 'none';
                break;
            case 'week':
                daySelector.style.display = 'block';
                dateSelector.style.display = 'none';
                daySelectorLabel.style.display = 'block';
                dateLabel.style.display = 'none';
                break;
            case 'month':
                daySelector.style.display = 'none';
                dateSelector.style.display = 'block';
                daySelectorLabel.style.display = 'none';
                dateLabel.style.display = 'block';
                break;
        }
    }

    function convertFrequencyToCron(automationId) {
        var frequencySelector = document.getElementById(`frequency-selector-${automationId}`);
        var daySelector = document.getElementById(`day-selector-${automationId}`);
        var dateSelector = document.getElementById(`date-selector-${automationId}`);
        var timeSelector = document.getElementById(`time-selector-${automationId}`);

        var hours = timeSelector.value.split(':')[0];
        var minutes = timeSelector.value.split(':')[1].split(' ')[0];

        var cronString = '';
        switch (frequencySelector.value) {
            case 'day':
                cronString = `${minutes} ${hours} * * *`;
                break;
            case 'week':
                cronString = `${minutes} ${hours} * * ${daySelector.value}`;
                break;
            case 'month':
                cronString = `${minutes} ${hours} ${dateSelector.value} * *`;
                break;
        }

        return cronString;
    }

    async function saveAutomation(automationId, create=false) {
        if ("{{ username }}" == "None") {
            url_encoded_href = encodeURIComponent(window.location.href);
            window.location.href = `/login?next=${url_encoded_href}`;
            return;
        }

        const scheduleEl = document.getElementById(`automation-schedule-${automationId}`);
        const notificationEl = document.getElementById(`automation-success-${automationId}`);
        const saveButtonEl = document.getElementById(`save-automation-button-${automationId}`);
        const queryToRunEl = document.getElementById(`automation-queryToRun-${automationId}`);
        const queryToRun = encodeURIComponent(queryToRunEl.value);
        const actOn = create ? "Creat" : "Sav";
        var cronTime = null;

        if (queryToRun == "") {
            if (!create && scheduleEl.value == "") {
                notificationEl.textContent = `⚠️ Failed to automate. All input fields need to be filled.`;
                notificationEl.style.display = "block";
                let originalQueryToRunElBorder = queryToRunEl.style.border;
                if (queryToRun === "") queryToRunEl.style.border = "2px solid red";
                let originalScheduleElBorder = scheduleEl.style.border;
                if (scheduleEl.value === "") scheduleEl.style.border = "2px solid red";
                setTimeout(function() {
                    if (queryToRun == "") queryToRunEl.style.border = originalQueryToRunElBorder;
                    if (scheduleEl.value == "") scheduleEl.style.border = originalScheduleElBorder;
                }, 2000);

                return;
            }

        }

        // Get client location information from IP
        const ip_response = await fetch("https://ipapi.co/json");
        let ip_data = null;
        if (ip_response.ok) {
            ip_data = await ip_response.json();
        }

        // Get cron string from natural language user schedule, if changed
        if (create && !scheduleEl) {
            crontime = convertFrequencyToCron(automationId);
        } else {
            crontime = scheduleEl.getAttribute('data-original') !== scheduleEl.value ? getCronString(scheduleEl.value) : scheduleEl.getAttribute('data-cron');
        }

        if (crontime.startsWith("ERROR:")) {
            notificationEl.textContent = `⚠️ Failed to automate. Fix or simplify Schedule input field.`;
            notificationEl.style.display = "block";
            let originalScheduleElBorder = scheduleEl.style.border;
            scheduleEl.style.border = "2px solid red";
            setTimeout(function() {
                scheduleEl.style.border = originalScheduleElBorder;
            }, 2000);

            return;
        }
        const encodedCrontime = encodeURIComponent(crontime);

        // Construct query string and select method for API call
        let query_string = `q=${queryToRun}&crontime=${encodedCrontime}`;
        if (ip_data) {
            query_string += `&city=${ip_data.city}&region=${ip_data.region}&country=${ip_data.country_name}&timezone=${ip_data.timezone}`;
        }

        let method = "POST";
        if (!create) {
            const subject = encodeURIComponent(document.getElementById(`automation-subject-${automationId}`).value);
            query_string += `&automation_id=${automationId}`;
            query_string += `&subject=${subject}`;
            method = "PUT"
        }

        // Create a loading animation while waiting for the API response
        // TODO add a more pleasant loading symbol here.
        notificationEl.textContent = `⏳ ${actOn}ing automation...`;
        notificationEl.style.display = "block";

        fetch(`/api/automation?${query_string}`, {
            method: method,
            headers: {
                'Content-Type': 'application/json',
            },
        })
        .then(response => response.ok ? response.json() : Promise.reject(data))
        .then(automation => {
            if (create) {
                const automationEl = document.getElementById(`automation-card-${automationId}`);
                // Create a more interesting confirmation animation.
                automationEl.classList.remove("new-automation");
                setTimeout(function() {
                    // Check if automationEl is a child of #automations or #suggested-automations-list
                    // If #suggested-automations-list, remove the element from the list and add it to #automations
                    let parentEl = automationEl.parentElement;
                    let isSuggested = parentEl.id === "suggested-automations-list";
                    if (isSuggested) {
                        parentEl.removeChild(automationEl);
                        document.getElementById("automations").prepend(automationEl);
                    }
                    automationEl.replaceWith(generateAutomationRow(automation));
                }, 1000);
            } else {
                updateAutomationRow(automation);
            }

            notificationEl.style.display = "none";
            saveButtonEl.textContent = `✅ Automation ${actOn}ed`;
            setTimeout(function() {
                const automationIDElements = document.querySelectorAll(`.${automationId}`);
                automationIDElements.forEach(el => {
                    // If it has the class automation-buttons, turn on the hide-details class
                    if (el.classList.contains("automation-buttons"))
                    {
                        el.classList.add("hide-details");
                    }
                    // If it has the class automationId, turn on the fake-input class
                    else if (el.classList.contains(automationId))
                    {
                        el.classList.add("fake-input");
                    }
                });
                saveButtonEl.textContent = "Save";
            }, 2000);
        })
        .catch(error => {
            notificationEl.textContent = `⚠️ Failed to ${actOn.toLowerCase()}e automation.`;
            notificationEl.style.display = "block";
            saveButtonEl.textContent = `⚠️ Failed to ${actOn.toLowerCase()}e automation`;
            setTimeout(function() {
                saveButtonEl.textContent = `${actOn}e`;
            }, 2000);
            return;
        });
    }

    const create_automation_button = document.getElementById("create-automation-button");
    create_automation_button.addEventListener("click", function(event) {
        event.preventDefault();
        var automationEl = document.createElement("div");
        automationEl.classList.add("card");
        automationEl.classList.add("automation");
        automationEl.classList.add("new-automation")
        const placeholderId = Date.now();
        automationEl.id = "automation-card-" + placeholderId;
        var scheduleSelector = createScheduleSelector(placeholderId);
        automationEl.innerHTML = `
            <label for="schedule">New Automation</label>
            ${scheduleSelector.outerHTML}
            <label for="query-to-run">What would you like to receive in your automation?</label>
            <textarea id="automation-queryToRun-${placeholderId}" placeholder="Provide me with a mindful moment, reminding me to be centered."></textarea>
            <div class="automation-buttons">
                <button type="button"
                        class="delete-automation-button negative-button"
                        onclick="deleteAutomation(${placeholderId}, true)"
                        id="delete-automation-button-${placeholderId}">Cancel</button>
                <button type="button"
                        class="save-automation-button"
                        onclick="saveAutomation(${placeholderId}, true)"
                        id="save-automation-button-${placeholderId}">Create</button>
            </div>
            <div id="automation-success-${placeholderId}" style="display: none;"></div>
        `;
        document.getElementById("automations").insertBefore(automationEl, document.getElementById("automations").firstChild);
        setupScheduleViewListener("* * * * *", placeholderId);
    })

    function createPreFilledAutomation(subject, crontime, query) {
        document.getElementById('overlay').style.display = 'block';
        var automationEl = document.createElement("div");
        automationEl.classList.add("card");
        automationEl.classList.add("automation");
        automationEl.classList.add("new-automation")
        const placeholderId = Date.now();
        automationEl.classList.add(`${placeholderId}`);
        automationEl.id = "automation-card-" + placeholderId;
        var scheduleSelector = createScheduleSelector(placeholderId);
        automationEl.innerHTML = `
            <label for="subject">New Automation</label>
            <input type="text" id="automation-subject-${placeholderId}" value="${subject}">
            ${scheduleSelector.outerHTML}
            <label for="query-to-run">What would you like to receive in your automation?</label>
            <textarea id="automation-queryToRun-${placeholderId}">${query}</textarea>
            <div class="automation-buttons">
                <button type="button"
                        class="delete-automation-button negative-button"
                        onclick="deleteAutomation(${placeholderId}, true)"
                        id="delete-automation-button-${placeholderId}">Cancel</button>
                <button type="button"
                        class="save-automation-button"
                        onclick="saveAutomation(${placeholderId}, true)"
                        id="save-automation-button-${placeholderId}">Create</button>
            </div>
            <div id="automation-success-${placeholderId}" style="display: none;"></div>
        `;
        document.getElementById("automations").insertBefore(automationEl, document.getElementById("automations").firstChild);
        setupScheduleViewListener(crontime, placeholderId);
    }

</script>
{% endblock %}
